import { Command } from "commander";
import chalk from "chalk";
import { table } from "table";
import { type TableUserConfig } from "table";
import { EslintPluginService, TaskResult } from "./Service.js";
import { getDefaultSpinner } from "../../utils/command-utils.js";
import { sleep } from "../../utils/tools.js";
import inquirer from "inquirer";

export class EslintPluginController {
  private service: EslintPluginService;
  private spinner = getDefaultSpinner();

  constructor() {
    this.service = new EslintPluginService();
  }

  /**
   * 显示任务执行结果表格
   */
  displayResultTable(): void {
    const results = this.service.getResults();
    if (results.length === 0) return;

    // 表头
    const header = ["任务名称", "任务状态", "任务耗时(ms)"];

    // 表格数据
    const data = [
      header,
      ...results.map((result) => [
        result.name,
        result.status === "success" ? chalk.green("成功") : chalk.red("失败"),
        result.duration.toString(),
      ]),
    ];

    // 表格配置
    const config: TableUserConfig = {
      columns: {
        0: { alignment: "center" },
        1: { alignment: "center" },
        2: { alignment: "center" },
      },
      border: {
        topBody: `─`,
        topJoin: `┬`,
        topLeft: `┌`,
        topRight: `┐`,
        bottomBody: `─`,
        bottomJoin: `┴`,
        bottomLeft: `└`,
        bottomRight: `┘`,
        bodyLeft: `│`,
        bodyRight: `│`,
        bodyJoin: `│`,
        joinBody: `─`,
        joinLeft: `├`,
        joinRight: `┤`,
        joinJoin: `┼`,
      },
    };

    console.log("\n执行结果汇总:");
    console.log(table(data, config));
  }

  /**
   * 验证命令参数
   */
  async onCommandConfirm(args: object, command: Command): Promise<void> {
    const taskType = command.opts()?.task || "";
    const projectType = command.opts().project || "";

    this.spinner.start("正在检测任务类型和项目类型...");
    await sleep(200);

    try {
      await this.service.validateCommand(taskType, projectType);
      this.spinner.succeed(`任务类型检测通过: ${taskType}`);
      this.spinner.succeed(`项目类型检测通过: ${projectType}`);
      return projectType;
    } catch (error: any) {
      this.spinner.fail(chalk.red(error.message));
      throw error;
    }
  }

  /**
   * 验证项目路径
   */
  async onPathConfirm(): Promise<void> {
    this.spinner.start("项目路径检测...");
    await sleep(200);

    try {
      await this.service.validatePath();
      this.spinner.succeed("项目路径检测通过: package.json 和 .git 存在");
    } catch (error: any) {
      this.spinner.fail(chalk.red(error.message));
      throw error;
    }
  }

  /**
   * 验证工作区状态
   */
  async onWorkspaceConfirm(): Promise<void> {
    this.spinner.start("正在检测工作区...");
    await sleep(200);

    try {
      await this.service.validateWorkspace();
      this.spinner.succeed("工作区检测通过: 工作区无未保存的变更");
    } catch (error: any) {
      this.spinner.fail(chalk.red(error.message));
      throw error;
    }
  }

  /**
   * 清理依赖
   */
  async onDependenciesClean(): Promise<void> {
    this.spinner.start(chalk.blue("正在删除 node_modules..."));
    await sleep(200);

    try {
      await this.service.cleanDependencies();
      this.spinner.succeed("node_modules 删除成功");
      this.spinner.succeed("eslint 和 prettier 相关依赖删除成功");
      this.spinner.succeed("package-lock.json 删除成功");
    } catch (error: any) {
      this.spinner.fail(chalk.red(error.message));
      throw error;
    }
  }

  /**
   * 清理配置文件
   */
  async onConfigFilesClean(): Promise<void> {
    this.spinner.start(
      chalk.blue("正在删除 eslint 和 prettier 相关配置文件...")
    );
    await sleep(200);

    try {
      await this.service.cleanConfigFiles();
      this.spinner.succeed("eslint 和 prettier 相关配置文件删除成功");
    } catch (error: any) {
      this.spinner.fail(chalk.red(error.message));
      throw error;
    }
  }

  /**
   * 创建配置文件
   */
  async onConfigFilesCreate(projectType: string): Promise<void> {
    this.spinner.start(chalk.blue("正在创建配置文件..."));
    await sleep(200);

    try {
      await this.service.createConfigFiles(projectType);
      this.spinner.succeed("eslint配置文件创建成功");
      this.spinner.succeed(".prettierrc 创建成功");
      this.spinner.succeed(".editorconfig 创建成功");
    } catch (error: any) {
      this.spinner.fail(chalk.red(error.message));
      throw error;
    }
  }

  /**
   * 更新 package.json 脚本
   */
  async onPackageScriptsUpdate(): Promise<void> {
    this.spinner.start(chalk.blue("正在创建 npm 命令..."));
    await sleep(200);

    try {
      await this.service.updatePackageScripts();
      this.spinner.succeed("npm 命令创建成功");
    } catch (error: any) {
      this.spinner.fail(chalk.red(error.message));
      throw error;
    }
  }

  /**
   * 安装依赖
   */
  async onDependenciesInstall(): Promise<void> {
    this.spinner.start(chalk.blue("正在安装 @zmn/eslint-plugin..."));
    try {
      await this.service.installDependencies();
      this.spinner.succeed("@zmn/eslint-plugin 安装成功");
      this.spinner.succeed("依赖安装成功");
    } catch (error: any) {
      this.spinner.fail(chalk.red(error.message));
      throw error;
    }
  }

  /**
   * 询问是否执行验证
   */
  async askForVerification(): Promise<boolean> {
    this.spinner.succeed("自动化任务执行成功，即将开始执行 eslint 验证...");
    async function confirmContinue() {
      const answers = await inquirer.prompt([
        {
          type: "input",
          name: "shouldContinue",
          message: "是否继续执行？(y/n): ",
          validate: (input) => {
            const validInputs = ["y", "n"];
            const normalizedInput = input.trim().toLowerCase();
            if (validInputs.includes(normalizedInput)) {
              return true;
            }
            return "输入无效，请输入正确字符 (y/n)。";
          },
        },
      ]);
      return answers.shouldContinue.trim().toLowerCase() === "y";
    }
    const shouldContinue = await confirmContinue();
    if (shouldContinue) {
      return true;
    } else {
      setTimeout(() => {
        process.exit(0);
      }, 200);
      return false;
    }
  }

  /**
   * 执行 ESLint 验证
   */
  async onEslintVerification(): Promise<void> {
    this.spinner.start(chalk.blue("正在执行 eslint 验证..."));
    await sleep(200);
    // this.spinner.start(chalk.blue("正在执行 npm run lint:script 命令..."));
    this.spinner.start(chalk.blue("正在执行 npx eslint.config.mjs 命令..."));
    try {
      await this.service.runEslintVerification();
      this.spinner.succeed(chalk.green("验证成功"));
    } catch (error: any) {
      this.spinner.fail(chalk.red(error.message));
      throw error;
    }
  }

  /**
   * 提交变更
   */
  async onChangesCommit(): Promise<void> {
    this.spinner.start(chalk.blue("正在提交变更..."));
    await sleep(200);

    try {
      await this.service.commitChanges();
      this.spinner.succeed(chalk.green("变更提交成功"));
    } catch (error: any) {
      this.spinner.fail(chalk.red(error.message));
      throw error;
    }
  }
}
